// Coypright (C) 2024 wlly-lzh
// Created by wlly-lzh on 24-5-22.
// 程序的一部分简单的功能

#include "func.h"

#define VESION "0.0.1"
void help(){
	printf("用法: \n");
	printf("      hfmzip [文件名] -o [压缩文件名]\n");
	printf("      hfmzip -X [压缩文件名] -o [文件名]\n");
	printf("哈夫曼压缩程序：\n");
	printf("可以对简单的文本文件进行压缩\n");
	printf("\n退出状态：\n");
	printf("0   正常\n");
	printf("1   文件问题\n");
	printf("2   参数问题\n");
}
void version(){
	printf("hfmzip %s\n",VESION);
	printf("Copyright (C) 2024 wlly-lzh\n");
}

void file_not_exit(){
	fprintf(stderr,"Error: 该文件不存在!\n");
}
void option_error(){
	fprintf(stderr,"选项错误！\n");
	fprintf(stderr,"请使用:hfmzip --help查看用法\n");
}
void compress(FILE *infile,FILE *outfile){
	head header[SIZE_HEAD]={0};
	fast_index index[ASCII_CIDE]={0};
	storage_tree tree[SIZE_HEAD];
	char buffer[64]="\0";
	unsigned char ch;
	int start,length;
	int num=head_of_file(infile,header,&length); // 初始化header
	start=create_huffman(header,num); // 创建哈夫曼树

	fwrite(&length,sizeof(int),1,outfile); // 写入原文件长度
	init_storage_tree(header,tree);  // 用于解码的哈夫曼表
	fwrite(&tree,sizeof(storage_tree),SIZE_HEAD,outfile);// 写入哈夫曼表

	create_index(header,index,start);    // 初始化索引
	fseek(infile,0,SEEK_SET);
	while(fread(&ch,sizeof(char),1,infile)==1){
		strcat(buffer,index[(int)ch].code);
		int l=strlen(buffer);
		while(l >= 8){
			ch=StrtoBin(buffer);
			fwrite(&ch,sizeof(unsigned char),1,outfile);
			strcpy(buffer,buffer+8);
			l=l-8;
		}
	}
	if(strlen(buffer) > 0){
		strcat(buffer,"00000000");
		ch=StrtoBin(buffer);
		fwrite(&ch, sizeof(unsigned char),1,outfile);
	}
	fclose(infile);
	fclose(outfile);
}

void uncompress(FILE * infile,FILE * outfile){
	int flength; //文件大小
	char ch,buffer[9]={0};
	unsigned char out;
	char ecode[64];
	storage_tree tree[SIZE_HEAD]; //哈夫曼表
	fread(&flength,sizeof(int),1,infile);
	fread(&tree,sizeof(storage_tree),SIZE_HEAD,infile);
	int start;
	Root(tree,&start);
	int addr=start;
	while(fread(&ch,sizeof(char),1,infile) == 1){
		BintoStr(ch,buffer);
		strcat(ecode,buffer);
		for(int i=0; ecode[i]!='\0'; ++i){
			bool success=find_element(tree,&addr,ecode[i],&out);
			if(success == true){
				fwrite(&out,sizeof(char),1,outfile);
				flength--;
				if(flength==0)
					break;
				addr=start;
			}
		}
		if(flength == 0)
			break;
		ecode[0]='\0';
	}
	fclose(infile);
	fclose(outfile);
}
